package com.chenfan.process.biz;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.chenfan.ccp.util.tool.UuidUtil;
import com.chenfan.process.entity.po.*;
import com.chenfan.process.service.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author K
 * @date 2022/6/27 11:22 AM
 */
@Slf4j
@Component
public class DataInitializerBiz {

    @Autowired
    private ApprovalTemplateService approvalTemplateService;
    @Autowired
    private ProcessRelatedService processRelatedService;
    @Autowired
    private ProcessDetailService processDetailService;
    @Autowired
    private ProcessRelatedAttributeService relatedAttributeService;
    @Autowired
    private ApprovalTemplateSnapshotService approvalTemplateSnapshotService;

    public void groupDataInit(List<Long> approvalTemplateIdList) {
        // 列出所有的模板
        List<ApprovalTemplatePo> approvalTemplatePos = approvalTemplateService.listAvailableApproval(approvalTemplateIdList);
        if (CollectionUtils.isEmpty(approvalTemplatePos)) {
            return;
        }
        List<Long> templateIdList = approvalTemplatePos.stream().map(ApprovalTemplatePo::getId).collect(Collectors.toList());

        // 查出所有的审批流关联关系
        List<ProcessRelatedPo> processRelatedList = processRelatedService.listProcessRelatedWithTemplate(templateIdList);

        // 先根据模板进行分组
        Map<Long, List<ProcessRelatedPo>> templateGroup = processRelatedList.stream().collect(Collectors.groupingBy(ProcessRelatedPo::getApprovalTemplateId));

        templateGroup.entrySet().forEach(e -> {
            Long approvalTemplateId = e.getKey();
            List<ProcessRelatedPo> related = e.getValue();
            // 根据版本分组
            Map<Long, List<ProcessRelatedPo>> versionMap = related.stream().collect(Collectors.groupingBy(ProcessRelatedPo::getVersion));

            versionMap.entrySet().forEach(o -> {
                Long version = o.getKey();
                List<ProcessRelatedPo> values = o.getValue().stream().filter(d -> !Objects.equals(d.getLinkType(), 0)).collect(Collectors.toList());
                // 判断哪些是属于需要增加GroupId的, 条件分支/会签/或签
                if (CollectionUtils.isEmpty(values)) {
                    // 不处理
                    return;
                }
                Map<Long, Long> groupCache = new HashMap<>();
                values.forEach(d -> {
                    // 如果有审批流配置了节点上带 或/会签功能. 先配置好对应的模板数据
                    if (Objects.nonNull(d.getGroupId())) {
                        // 如果本来就有groupId, 直接设置值
                        groupCache.put(d.getProcessBeforeId(), d.getGroupId());
                        return;
                    }

                    Long groupId = groupCache.get(d.getProcessBeforeId());
                    if (Objects.isNull(groupId)) {
                        groupId = UuidUtil.generateId();
                        groupCache.put(d.getProcessBeforeId(), groupId);
                    }
                    d.setGroupId(groupId);
                });
                processRelatedService.updateBatchById(values);

                List<Long> beforeList = values.stream().map(ProcessRelatedPo::getProcessBeforeId).collect(Collectors.toList());

                // 查询Detail数据, 进行groupId更新
                List<ProcessDetailPo> processDetailPos = processDetailService.listGroupInitData(approvalTemplateId, beforeList);
                if (CollectionUtils.isEmpty(processDetailPos)) {
                    return;
                }
                processDetailPos.forEach(d -> {
                    Long groupId = groupCache.getOrDefault(d.getProcessId(), null);
                    d.setGroupId(groupId);
                });
                // 批量更新
                processDetailService.updateBatchById(processDetailPos);
                log.info("templateId:{}, version:{}", approvalTemplateId, version);
            });
        });
    }

    public void relatedGroupInit(List<Long> approvalTemplateIdList) {
        List<ApprovalTemplatePo> approvalTemplatePos = approvalTemplateService.listAvailableApproval(approvalTemplateIdList);
        if (CollectionUtils.isEmpty(approvalTemplatePos)) {
            return;
        }
        List<Long> templateIdList = approvalTemplatePos.stream().map(ApprovalTemplatePo::getId).collect(Collectors.toList());


        // 查出所有的审批流关联关系
        List<ProcessRelatedAttribute> attributeList =  relatedAttributeService.listWithTemplateId(templateIdList);
        Map<Long, List<ProcessRelatedAttribute>> templateGroupMap = attributeList.stream().collect(Collectors.groupingBy(ProcessRelatedAttribute::getApprovalTemplateId));
        templateGroupMap.forEach((key1, values) -> {
            // 分版本处理
            Map<Long, List<ProcessRelatedAttribute>> versionMap = values.stream().collect(Collectors.groupingBy(ProcessRelatedAttribute::getVersion));
            versionMap.forEach((key, versionList) -> {
                // 分relatedId处理
                versionList.stream().collect(Collectors.groupingBy(ProcessRelatedAttribute::getRelatedId)).forEach((key2, value) -> {
                    Long groupId = UuidUtil.generateId();
                    value.forEach(v -> v.setGroupId(groupId));
                });
            });
        });
        // 最终批量更新
        relatedAttributeService.updateBatchById(attributeList);
    }

    public void refreshTemplateSnapshot(List<Long> approvalTemplateIdList) {
        List<ApprovalTemplateSnapshotPo> approvalTemplateSnapshots = approvalTemplateSnapshotService.listTemplate(approvalTemplateIdList);

        approvalTemplateSnapshots.forEach(e -> {
            JSONObject jsonObject = JSONObject.parseObject(e.getContent(), JSONObject.class);
            // 解析数据
            JSONArray linkDataArray = jsonObject.getJSONArray("linkDataArray");

            for(int i = 0; i < linkDataArray.size(); i++) {
                JSONObject linkData = linkDataArray.getJSONObject(i);
                JSONArray wrapper = new JSONArray();
                JSONArray attributes = linkData.getJSONArray("attributes");
                if (CollectionUtils.isEmpty(attributes)) {
                    continue;
                }

                // 如果是JsonObject对象的
                boolean match = attributes.stream().allMatch(o -> o.getClass().equals(JSONObject.class));
                if (match) {
                    // 再套上一层数据
                    wrapper.add(attributes);
                    linkData.put("attributes", wrapper);
                }
            }
            jsonObject.put("linkDataArray", linkDataArray);
            e.setContent(jsonObject.toJSONString());
        });

        approvalTemplateSnapshotService.updateBatchById(approvalTemplateSnapshots);
    }

    public void splitTemplateSnapshot(List<Long> approvalTemplateIdList) {
        List<ApprovalTemplateSnapshotPo> approvalTemplateSnapshots = approvalTemplateSnapshotService.listTemplate(approvalTemplateIdList);

        approvalTemplateSnapshots.forEach(e -> {
            JSONObject jsonObject = JSONObject.parseObject(e.getContent(), JSONObject.class);
            // 解析数据
            JSONArray linkDataArray = jsonObject.getJSONArray("linkDataArray");

            for(int i = 0; i < linkDataArray.size(); i++) {
                JSONObject linkData = linkDataArray.getJSONObject(i);
                JSONArray attributes = linkData.getJSONArray("attributes");
                if (CollectionUtils.isEmpty(attributes)) {
                    continue;
                }

                JSONArray replaceAttributes = new JSONArray();

                // 判断属性内容
                attributes.forEach(o -> {
                    JSONArray data = (JSONArray) o;
                    boolean match = data.stream().allMatch(d -> {
                        JSONObject obj = (JSONObject) d;
                        Integer relation = obj.getInteger("relation");
                        return Objects.equals(relation, 1);
                    });

                    if (match) {
                        // 拆分组.
                        replaceAttributes.addAll(data.stream().map(Collections::singleton).collect(Collectors.toList()));
                        linkData.put("attributes", replaceAttributes);
                    }
                    jsonObject.put("linkDataArray", linkDataArray);
                });

            }
            e.setContent(jsonObject.toJSONString());
        });
        approvalTemplateSnapshotService.updateBatchById(approvalTemplateSnapshots);
    }
}
